<?php

namespace App\Providers;

use Exception;
use Phalcon\Mvc\Dispatcher;
use Phalcon\Events\Event;
use Phalcon\Events\Manager as EventsManager;
use Phalcon\Http\Request;
use App\Util\Fun;

/**
 * \App\Providers\MvcDispatcherServiceProvider
 *
 * @package App\Providers
 */
class MvcDispatcherServiceProvider extends AbstractServiceProvider
{
    /**
     * The Service name.
     * @var string
     */
    protected $serviceName = 'dispatcher';

    /**
     * This namespace is applied to the controller routes in your routes file.
     * @var string
     */
    protected $namespace = 'App\Http\Controllers';

    /**
     * Register application service.
     *
     * @return void
     */
    public function register()
    {
        $namespace = $this->namespace;
		
        $this->di->setShared(
            $this->serviceName,
            function () use ($namespace) {
				$f = new Fun;
				$eventsManager = new EventsManager;
				$eventsManager->attach('dispatch:beforeDispatch', function(Event $event, Dispatcher $dispatcher){
					$request = new Request();
					$controller = $dispatcher->getControllerName();
					$action = $dispatcher->getActionName();
					if(!$request->isPost() && $controller != 'error'){
						$dispatcher->forward(["controller" => "error",'action'=>'notpost']);
						return false;
					}
					$raw_body = $request->getRawBody();
					if($raw_body && substr($raw_body,0,1) == "{" && !$request->getJsonRawBody() && $controller != 'error'){
						$dispatcher->forward(["controller" => "error",'action'=>'notjson']);
						return false;
					}
					
				});
				
				$eventsManager->attach('dispatch:beforeException', function(Event $event, Dispatcher $dispatcher, Exception $exception) use($f) {
					
					 if ($exception instanceof DispatchException) {
						$f->echoJson('Request Not Found',404);
					 }
					 
					 switch ($exception->getCode()) {
						case Dispatcher::EXCEPTION_HANDLER_NOT_FOUND:
						case Dispatcher::EXCEPTION_ACTION_NOT_FOUND:
							$f->echoJson('Request Not Found',404);
					 }
					 
					 $f->echoJson($exception->getMessage(),401);

				});
				
                $dispatcher = new Dispatcher();
                $dispatcher->setDefaultNamespace($namespace);
				$dispatcher->setEventsManager($eventsManager);
				
                return $dispatcher;
            }
        );
    }
}
